home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Programming / HunkFunc / Source / HunkFunc.c next >
Encoding:
C/C++ Source or Header  |  2001-06-23  |  16.7 KB  |  654 lines

  1. #define NAME     "HunkFunc"
  2. #define REVISION "14"
  3. #define DATE     "17.06.2001"
  4.  
  5. /* Programmheader
  6.  
  7.     Name:        HunkFunk
  8.     Author:        SDI
  9.     Distribution:    PD
  10.     Description:    object/binary file scanner
  11.     Compileropts:    -
  12.     Linkeropts:    -gsi -l amiga
  13.  
  14.  1.0   12.02.98 : made with help of Olaf 'Olsen' Barthel's HunkFunk
  15.  1.1   23.03.98 : now prints reloc infos
  16.  1.2   23.11.98 : added new overlay format
  17.  1.3   09.12.98 : added CHIP, FAST, ADVISORY to CODE/DATA/BSS hunks
  18.  1.4   28.12.98 : unknown hunk now prints 8 digits
  19.  1.5   30.08.99 : 4 new switches for command line, fixed lots of stuff
  20.  1.6   13.09.99 : better support for Overlay files
  21.  1.7   15.09.99 : changed overlay support, added SOVT keyword
  22.  1.8   27.09.99 : displays extra stuff message
  23.  1.9   03.11.99 : added number of EXT_REF's
  24.  1.10  13.11.99 : added H&P EHF stuff
  25.  1.11  29.11.99 : added CTRL_C to reloc print
  26.  1.12  26.06.00 : added abort for defective relocs, fixed overflow bugs
  27.  1.13  03.06.01 : added EXT_REF display
  28.  1.14  17.06.01 : added SEREF argument
  29. */
  30.  
  31. #include <proto/dos.h>
  32. #include <proto/exec.h>
  33. #include <exec/memory.h>
  34. #include <dos/doshunks.h>
  35. #include "SDI_version.h"
  36. #define SDI_TO_ANSI
  37. #include "SDI_ASM_STD_protos.h"
  38.  
  39. /* CHIP, FAST and ADVISORY information is repeated in hunk itself. If
  40. the word is used normally, the information is in second longword (size).
  41. If it is preceeded by a '_', the information is in first longword (hunk
  42. type). */
  43.  
  44. #define PARAM "FILE/M/A,SREL=SHOWRELOC/S,SSYM=SHOWSYMBOL/S,SEXT=SHOWEXTERN/S,SEREF=SHOWEXTERNREF/S," \
  45.               "SOVT=SHOWOVERLAYTABLE/S,STATS/S"
  46.  
  47. /* Some simple macros. */
  48. #define ReadLong(Type)      Read(FileHandle, (Type), 4)
  49. #define ReadWord(Type)      Read(FileHandle, (Type), 2)
  50. #define ReadName(Longs)   Read(FileHandle, NameString, 4 * (Longs))
  51. #define SkipLong(Longs)   Seek(FileHandle, 4 * (Longs), OFFSET_CURRENT)
  52. #define SkipWord(Words)      Seek(FileHandle, 2* (Words), OFFSET_CURRENT)
  53. #define SkipByte(Bytes)      Seek(FileHandle, (Bytes), OFFSET_CURRENT)
  54. #define MakeName(Longs)   NameString[(Longs) * 4] = 0
  55. #define GetHunkName(Type) HunkNames[(Type)-HUNK_UNIT]
  56. #define CTRL_C          (SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  57.  
  58. STRPTR HunkNames[] = { /* access them with HunkNames[Type-HUNK_UNIT] */
  59. "HUNK_UNIT",    "HUNK_NAME",    "HUNK_CODE",    "HUNK_DATA",    "HUNK_BSS", 
  60. "HUNK_(ABS)RELOC32",    "HUNK_(REL)RELOC16",    "HUNK_(REL)RELOC8",    "HUNK_EXT",    "HUNK_SYMBOL",
  61. "HUNK_DEBUG",    "HUNK_END",    "HUNK_HEADER",    "",        "HUNK_OVERLAY",
  62. "HUNK_BREAK",    "HUNK_DREL32",    "HUNK_DREL16",    "HUNK_DREL8",    "HUNK_LIB",
  63. "HUNK_INDEX",    "HUNK_RELOC32SHORT",    "HUNK_RELRELOC32",    "HUNK_ABSRELOC16",
  64. "HUNK_DREL32EXE"
  65. };
  66.  
  67. #define HUNK_DREL32EXE    (HUNK_ABSRELOC16+1)
  68.  
  69. #define HUNK_PPC_CODE    0x4E9
  70. #define HUNK_RELRELOC26    0x4EC
  71. #define EXT_RELREF26    229
  72.  
  73. struct Args {
  74.   STRPTR * files;
  75.   ULONG    showreloc;
  76.   ULONG    showsymbol;
  77.   ULONG    showextern;
  78.   ULONG    showexternref;
  79.   ULONG       showoverlaytable;
  80.   ULONG    stats;
  81. };
  82.  
  83. struct Stats {
  84.   ULONG Header;
  85.   ULONG Unit;
  86.   ULONG Lib;
  87.   ULONG Code;
  88.   ULONG Data;
  89.   ULONG BSS;
  90.   ULONG Debug;
  91.   ULONG Symbol;
  92.   ULONG Extern;
  93.   ULONG Reloc;
  94.   ULONG NumSymbol;
  95.   ULONG NumReloc;
  96.   ULONG NumExtern;
  97.   ULONG CodeSize;
  98.   ULONG DataSize;
  99.   ULONG BSSSize;
  100.   ULONG DebugSize;
  101.   ULONG PPCCode;
  102.   ULONG PPCCodeSize;
  103. };
  104.  
  105. struct DosLibrary *DOSBase = 0;
  106. struct ExecBase * SysBase  = 0;
  107.  
  108. STRPTR GetTabs(STRPTR);
  109. void ShowStats(struct Stats *);
  110. LONG ProcessFile(ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, struct Stats *);
  111.  
  112. ULONG start(void)
  113. {
  114.   ULONG ret = RETURN_FAIL;
  115.   struct DosLibrary *dosbase;
  116.   SysBase = (*((struct ExecBase **) 4));
  117.  
  118.   { /* test for WB and reply startup-message */
  119.     struct Process *task;
  120.     if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  121.     {
  122.       WaitPort(&task->pr_MsgPort);
  123.       Forbid();
  124.       ReplyMsg(GetMsg(&task->pr_MsgPort));
  125.       return RETURN_FAIL;
  126.     }
  127.   }
  128.  
  129.   if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  130.   {
  131.     struct Args args;
  132.     struct RDArgs *rda;
  133.  
  134.     DOSBase = dosbase;
  135.  
  136.     memset(&args, 0, sizeof(struct Args));
  137.     if((rda = ReadArgs(PARAM, (LONG *) &args, 0)))
  138.     {
  139.       ret = 0;
  140.       while(*args.files)
  141.       {
  142.         ULONG err, fh;
  143.  
  144.         if((fh = Open(*args.files, MODE_OLDFILE)))
  145.         {
  146.       struct Stats stats;
  147.  
  148.           Printf("File '%s':\n", *args.files);
  149.           memset(&stats, 0, sizeof(struct Stats));
  150.           err = ProcessFile(fh, args.showreloc, args.showsymbol, args.showextern, args.showexternref,
  151.           args.showoverlaytable, &stats);
  152.           if(err == 2)
  153.             Printf("Unexpected end of file.\n");
  154.           if(args.stats)
  155.             ShowStats(&stats);
  156.           Close(fh);
  157.         }
  158.         else
  159.           PrintFault(IoErr(), *args.files);
  160.         if(CTRL_C)
  161.           SetIoErr(ERROR_BREAK);
  162.         ++args.files;
  163.       }
  164.     }
  165.     
  166.     if(ret)
  167.       PrintFault(IoErr(), 0);
  168.  
  169.     CloseLibrary((struct Library *) dosbase);
  170.   }
  171.   return ret;
  172. }
  173.  
  174. STRPTR GetTabs(STRPTR NameString)
  175. {
  176.   ULONG i = 0;
  177.  
  178.   while(*(NameString++) && i < 24)
  179.    ++i;
  180.   i >>= 3;
  181.   
  182.   return "\t\t\t"+i;
  183. }
  184.  
  185. void ShowStats(struct Stats *stats)
  186. {
  187.   Printf("STATISTICS:\nFile type\t");
  188.   if(stats->PPCCode)
  189.     Printf("PPC-WOS Objectfile");
  190.   else if(stats->Header)
  191.     Printf("Executable");
  192.   else if(stats->Lib)
  193.     Printf("New style link library");
  194.   else if(stats->Unit > 1)
  195.     Printf("Old style link library");
  196.   else
  197.     Printf("Objectfile");
  198.   Printf("\n");
  199.  
  200.   Printf("HUNK_CODE\t%6ld with total %6ld ($%06lx) Bytes\n", stats->Code, stats->CodeSize, stats->CodeSize);
  201.   if(stats->PPCCode)
  202.     Printf("HUNK_PPC_CODE\t%6ld with total %6ld ($%06lx) Bytes\n", stats->PPCCode, stats->PPCCodeSize, stats->PPCCodeSize);
  203.   Printf("HUNK_DATA\t%6ld with total %6ld ($%06lx) Bytes\n", stats->Data, stats->DataSize, stats->DataSize);
  204.   Printf("HUNK_BSS\t%6ld with total %6ld ($%06lx) Bytes\n", stats->BSS, stats->BSSSize, stats->BSSSize);
  205.   Printf("HUNK_DEBUG\t%6ld with total %6ld ($%06lx) Bytes\n", stats->Debug, stats->DebugSize, stats->DebugSize);
  206.   Printf("HUNK_EXT\t%6ld with total %6ld entr%s\n", stats->Extern, stats->NumExtern, stats->NumExtern == 1 ? "y" : "ies");
  207.   Printf("HUNK_RELOC\t%6ld with total %6ld entr%s\n", stats->Reloc, stats->NumReloc, stats->NumReloc == 1 ? "y" : "ies");
  208.   Printf("HUNK_SYMBOL\t%6ld with total %6ld entr%s\n", stats->Symbol, stats->NumSymbol, stats->NumSymbol == 1 ? "y" : "ies");
  209. }
  210.  
  211. /* return 0 on error */
  212. LONG ProcessFile(ULONG FileHandle, ULONG showreloc, ULONG showsymbol, ULONG showextern, ULONG showexternref, 
  213. ULONG showoverlaytable, struct Stats *stats)
  214. {
  215.   ULONG Type, Data, i;
  216.   UBYTE NameString[257];
  217.  
  218.   while(!CTRL_C)
  219.   {
  220.     if((i = ReadLong(&Type)) != 4)
  221.     {
  222.       if(i)
  223.         Printf("There %s %ld extra byte%s at end of file.\n", i == 1 ? "is" : "are", i, i == 1 ? "" : "s");
  224.       return 0;
  225.     }
  226.  
  227.     if(Type == HUNK_DREL32 && stats->Header)
  228.       Type = HUNK_DREL32EXE;
  229.  
  230.     /* Look which type it is. */
  231.     switch(Type & 0xFFFF)
  232.     {
  233.     case HUNK_UNIT:
  234.       ++stats->Unit;
  235.       ReadLong(&Data);
  236.       if(Data)
  237.         ReadName(Data);
  238.       MakeName(Data);
  239.       Printf("%s\t\"%s\"\n\n", GetHunkName(Type), NameString);
  240.       break;
  241.     case HUNK_NAME:
  242.       ReadLong(&Data);
  243.       if(Data)
  244.         ReadName(Data);
  245.       MakeName(Data);
  246.       Printf("%s\t\"%s\"\n", GetHunkName(Type), NameString);
  247.       break;
  248.     case HUNK_LIB:
  249.       ++stats->Lib;
  250.       ReadLong(&Data);
  251.       Printf("%s\t%6ld ($%06lx) Bytes\n\n", GetHunkName(Type), Data, Data);
  252.       break;
  253.     case HUNK_INDEX:
  254.       {
  255.         UWORD dat2;
  256.  
  257.         ReadLong(&Data);
  258.         Printf("%s\t%6ld ($%06lx) Bytes\n", GetHunkName(Type), Data, Data);
  259.         ReadWord(&dat2);
  260.         SkipByte((Data*4)-2);
  261.     Printf("  Textsize =\t%6ld Bytes\n\n", dat2);
  262.       }
  263.       break;
  264.     case HUNK_CODE: case HUNK_DATA: case HUNK_BSS:
  265.       ReadLong(&Data);
  266.       i = Data;
  267.       Data <<= 2;
  268.       Data &= 0x7FFFFFFF;
  269.       switch(Type&0xFFFF)
  270.       {
  271.       case HUNK_CODE: ++stats->Code; stats->CodeSize += Data; SkipByte(Data); break;
  272.       case HUNK_DATA: ++stats->Data; stats->DataSize += Data; SkipByte(Data); break;
  273.       case HUNK_BSS: ++stats->BSS; stats->BSSSize += Data; break;
  274.       }
  275.       Printf("%s\t%6ld ($%06lx) Bytes", GetHunkName(Type), Data, Data);
  276.       if(Type & HUNKF_CHIP)        Printf(" _CHIP");
  277.       if(Type & HUNKF_FAST)        Printf(" _FAST");
  278.       if(Type & HUNKF_ADVISORY)     Printf(" _ADVISORY");
  279.       if(i & HUNKF_CHIP)        Printf(" CHIP");
  280.       if(i & HUNKF_FAST)        Printf(" FAST");
  281.       if(i & HUNKF_ADVISORY)         Printf(" ADVISORY");
  282.       Printf("\n");
  283.       break;
  284.     case HUNK_PPC_CODE:
  285.       ReadLong(&Data);
  286.       i = Data;
  287.       Data <<= 2;
  288.       Data &= 0x7FFFFFFF;
  289.       ++stats->PPCCode; stats->PPCCodeSize += Data;
  290.       SkipByte(Data);
  291.       Printf("HUNK_PPC_CODE\t%6ld ($%06lx) Bytes", Data, Data);
  292.       if(Type & HUNKF_CHIP)        Printf(" _CHIP");
  293.       if(Type & HUNKF_FAST)        Printf(" _FAST");
  294.       if(Type & HUNKF_ADVISORY)     Printf(" _ADVISORY");
  295.       if(i & HUNKF_CHIP)        Printf(" CHIP");
  296.       if(i & HUNKF_FAST)        Printf(" FAST");
  297.       if(i & HUNKF_ADVISORY)         Printf(" ADVISORY");
  298.       Printf("\n");
  299.       break;
  300.     case HUNK_RELRELOC32: case HUNK_ABSRELOC16: case HUNK_RELRELOC26:
  301.     case HUNK_RELOC32: case HUNK_RELOC16: case HUNK_RELOC8:
  302.     case HUNK_DREL32: case HUNK_DREL16: case HUNK_DREL8:
  303.       if(Type == HUNK_RELRELOC26)
  304.         Printf("HUNK_RELRELOC26\n");
  305.       else
  306.         Printf("%s\n", GetHunkName(Type));
  307.       ++stats->Reloc;
  308.  
  309.       do
  310.       {
  311.     if(ReadLong(&Data) != 4)
  312.       return 2;
  313.     if(Data)
  314.     {
  315.       ULONG dat2 = 0, dat3;
  316.       ReadLong(&dat2);
  317.       stats->NumReloc += Data;
  318.       Printf("  Summary\t%6ld entr%s to hunk %ld%s\n", Data,
  319.       Data == 1 ? "y" : "ies", dat2, Data > 0xFFFF ? " (LoadSeg fails)" : "");
  320.       if(showreloc)
  321.       {
  322.         for(dat3 = Data; dat3 && !CTRL_C; --dat3)
  323.         {
  324.           if(ReadLong(&dat2) != 4)
  325.             return 2;
  326.           Printf("  Offset\t\t$%08lx\n", dat2);
  327.         }
  328.       }
  329.       else
  330.         SkipLong(Data);
  331.     }
  332.       } while(!CTRL_C && Data);
  333.       break;
  334.     case HUNK_RELOC32SHORT: case HUNK_DREL32EXE:
  335.       {
  336.         UWORD Data = 0;
  337.         ULONG nums = 0;
  338.         Printf("%s\n", GetHunkName(Type));
  339.         ++stats->Reloc;
  340.  
  341.         do
  342.         {
  343.       UWORD dat2 = 0;
  344.       ULONG dat3;
  345.       if(ReadWord(&Data) != 2)
  346.         return 2;
  347.       if(Data)
  348.       {
  349.             ReadWord(&dat2);
  350.             stats->NumReloc += Data;
  351.         Printf("  Summary\t%6ld entr%s to hunk %ld\n", Data,
  352.         Data == 1 ? "y" : "ies", dat2);
  353.         if(showreloc)
  354.         {
  355.           for(dat3 = Data; dat3 && !CTRL_C; --dat3)
  356.           {
  357.             if(ReadWord(&dat2) != 2)
  358.               return 2;
  359.             Printf("  Offset\t\t$%04lx\n", dat2);
  360.           }
  361.         }
  362.         else
  363.           SkipWord(Data);
  364.         nums += Data;
  365.       }
  366.         } while(!CTRL_C && Data);
  367.         if(!(nums & 1))
  368.           SkipWord(1);
  369.       }
  370.       break;
  371.     case HUNK_EXT:
  372.       Printf("HUNK_EXT\n");
  373.       ++stats->Extern;
  374.  
  375.       do
  376.       {
  377.     LONG i;
  378.  
  379.         ReadLong(&Data);
  380.         if(!Data)
  381.       break;
  382.     ++stats->NumExtern;
  383.     if(showextern)
  384.     {
  385.           switch((Data >> 24) & 0xFF)
  386.       {
  387.       case EXT_DEF:       Printf("  EXT_DEF"); break;
  388.       case EXT_ABS:       Printf("  EXT_ABS"); break;
  389.       case EXT_RES:       Printf("  EXT_RES"); break;
  390.       case EXT_REF32:     Printf("  EXT_REF32"); break;
  391.       case EXT_COMMON:    Printf("  EXT_COMMON"); break;
  392.       case EXT_REF16:     Printf("  EXT_REF16"); break;
  393.       case EXT_REF8:      Printf("  EXT_REF8"); break;
  394.       case EXT_DEXT32:    Printf("  EXT_DEXT32"); break;
  395.       case EXT_DEXT16:    Printf("  EXT_DEXT16"); break;
  396.       case EXT_DEXT8:     Printf("  EXT_DEXT8"); break;
  397.       case EXT_RELREF32:  Printf("  EXT_RELREF32"); break;
  398.       case EXT_RELREF26:  Printf("  EXT_RELREF26"); break;
  399.       case EXT_RELCOMMON: Printf("  EXT_RELCOMMON"); break;
  400.       default: Printf("  EXT_??? ($%02x)\n",(Data >> 24) & 0xFF);
  401.         break;
  402.           }
  403.         }
  404.  
  405.     /* Is it followed by a symbol name? */
  406.  
  407.     if(Data & 0xFFFFFF)
  408.     {
  409.       ReadName(Data & 0xFFFFFF);
  410.       MakeName(Data & 0xFFFFFF);
  411.       if(showextern)
  412.             Printf("\t%s", NameString);
  413.         }
  414.  
  415.     /* Remember extension type. */
  416.         i = (Data >> 24) & 0xFF;
  417.  
  418.     /* Display value of symbol. */
  419.         if(i == EXT_DEF || i == EXT_ABS || i == EXT_RES)
  420.         {
  421.       if(!(Data & 0xFFFFFF) && showextern)
  422.         Printf("\t???");
  423.  
  424.       ReadLong(&Data);
  425.       if(showextern)
  426.         Printf("%s= $%08lx", GetTabs(NameString), Data);
  427.     }
  428.  
  429.     /* Skip relocation information. */
  430.         if(i == EXT_REF32 || i == EXT_REF16 || i == EXT_REF8 ||
  431.         i == EXT_DEXT32 || i == EXT_DEXT16 || i == EXT_DEXT8 ||
  432.         i == EXT_RELREF32 || i == EXT_RELREF26)
  433.     {
  434.       ReadLong(&Data);
  435.       if(showextern)
  436.       {
  437.         ULONG d;
  438.  
  439.         if(Data > 1)
  440.         {
  441.           Printf("%s= %ld entries", GetTabs(NameString), Data);
  442.           if(showexternref)
  443.           {
  444.             while(Data--)
  445.             {
  446.               ReadLong(&d);
  447.               Printf("\n\t\t%s= $%08lx", GetTabs(""), d);
  448.             }
  449.           }
  450.           else
  451.             SkipLong(Data);
  452.         }
  453.         else
  454.         {
  455.           ReadLong(&d);
  456.           Printf("%s= $%08lx (1 entry)", GetTabs(NameString), d);
  457.         }
  458.       }
  459.       else
  460.         SkipLong(Data);
  461.     }
  462.  
  463.     /* Display size of common block. */
  464.         if(i == EXT_COMMON || i == EXT_RELCOMMON)
  465.     {
  466.       ReadLong(&Data);
  467.  
  468.       if(showextern)
  469.         Printf("\tSize = %ld Bytes", Data << 2);
  470.       ReadLong(&Data);
  471.       SkipLong(Data);
  472.     }
  473.     if(showextern)
  474.           Printf("\n");
  475.       } while(!CTRL_C);
  476.       break;
  477.     case HUNK_SYMBOL:
  478.       Printf("HUNK_SYMBOL\n");
  479.       ++stats->Symbol;
  480.  
  481.       do
  482.       {
  483.     ReadLong(&Data);
  484.  
  485.     if(!Data)
  486.       break;
  487.  
  488.     ++stats->NumSymbol;
  489.     /* Display name. */
  490.         ReadName(Data & 0xFFFFFF);
  491.         MakeName(Data & 0xFFFFFF);
  492.  
  493.     if(showsymbol)
  494.           Printf("  Symbol\t%s", NameString);
  495.  
  496.     /* Display value. */
  497.         ReadLong(&Data);
  498.  
  499.     if(showsymbol)
  500.       Printf("%s= $%08lx\n", GetTabs(NameString), Data);
  501.       } while(!CTRL_C);
  502.       break;
  503.     case HUNK_DEBUG:
  504.       ++stats->Debug;
  505.       ReadLong(&Data);
  506.       SkipLong(Data);
  507.       Data <<= 2;
  508.       stats->DebugSize += Data;
  509.       Printf("HUNK_DEBUG\t%6ld ($%06lx) Bytes\n", Data, Data);
  510.       break;
  511.     case HUNK_END:
  512.       Printf("HUNK_END\n\n");
  513.       break;
  514.     case HUNK_HEADER:
  515.       Printf("HUNK_HEADER\n");
  516.  
  517.       ++stats->Header;
  518.  
  519.       do
  520.       {
  521.         ULONG data2;
  522.  
  523.     if(ReadLong(&Data) != 4)
  524.       return 2;
  525.  
  526.     /* Display names of resident libraries. */
  527.         if(!Data)
  528.           break;
  529.  
  530.     if((data2 = Data) > 64)
  531.       data2 = 64;
  532.     Data -= data2;
  533.  
  534.     if(ReadName(data2) != 4*data2)
  535.       return 2;
  536.     if(Data && SkipLong(Data) < 0)
  537.       return 2;
  538.     MakeName(data2);
  539.  
  540.     Printf("  Name =\t%s\n", NameString);
  541.       } while(!CTRL_C);
  542.  
  543.       if(!CTRL_C)
  544.       {
  545.         LONG i,From,To;
  546.  
  547.         ReadLong(&Data);
  548.  
  549.     Printf("  Numhunks =\t%6ld (", Data);
  550.         ReadLong(&From);
  551.         Printf("%ld to ", From);
  552.         ReadLong(&To);
  553.         Printf("%ld)\n",To);
  554.  
  555.         /* Display hunk lengths/types. */
  556.         for(i = 0; !CTRL_C && i < To - From + 1; ++i)
  557.         {
  558.       ReadLong(&Data);
  559.           Printf("  Hunk %03ld =\t%6ld ($%06lx) Bytes", i,
  560.           (Data & 0x3FFFFFFF) << 2, (Data & 0x3FFFFFFF) << 2);
  561.  
  562.       if((Data & HUNKF_CHIP) && (Data & HUNKF_FAST))
  563.       {    /* extended type */
  564.         ULONG t;
  565.         ReadLong(&t);
  566.         Printf(" MEMTYPE($%08lx)", t);
  567.       }
  568.       else
  569.       {
  570.             if(Data & HUNKF_CHIP)    Printf(" CHIP");
  571.             if(Data & HUNKF_FAST)    Printf(" FAST");
  572.           }
  573.           if(Data & HUNKF_ADVISORY)    Printf(" ADVISORY");
  574.  
  575.       Printf("\n");
  576.         }
  577.         Printf("\n");
  578.       }
  579.       break;
  580.     case HUNK_OVERLAY:
  581.       {
  582.         LONG TabSize, Data, Data2 = 0;
  583.         ULONG *ovt = 0;
  584.         Printf("HUNK_OVERLAY\n");
  585.         ReadLong(&TabSize);
  586.  
  587.     Printf("  TableSize\t%6ld ($%06lx) Bytes\n", TabSize*4, TabSize*4);
  588.  
  589.     if(TabSize)
  590.     {
  591.       ReadLong(&Data2);
  592.       if(showoverlaytable && (ovt = (ULONG *) AllocVec(TabSize*4, MEMF_ANY)))
  593.         Read(FileHandle, ovt, TabSize*4);
  594.       else
  595.         SkipLong(TabSize);
  596.     }
  597.     ReadLong(&Data);
  598.     if(!TabSize && Data == HUNK_BREAK)
  599.     {
  600.       Data = Seek(FileHandle, 0, OFFSET_END);
  601.       Data = Seek(FileHandle, 0, OFFSET_END) - Data;
  602.       Printf("HUNK_BREAK\n\nLeft Space\t%6ld ($%06lx) Bytes\n", Data, Data);
  603.     }
  604.     else if(TabSize && Data >= HUNK_UNIT && Data <= HUNK_ABSRELOC16)
  605.     {
  606.       Seek(FileHandle, -4, OFFSET_CURRENT);
  607.       Printf("  Levels\t%6ld\n", Data2-2);
  608.       Printf("  Entries\t%6ld\n", (TabSize-Data2+1) >> 3);
  609.     }
  610.     else
  611.     {
  612.       Data = Seek(FileHandle, 0, OFFSET_END);
  613.       Data = Seek(FileHandle, 0, OFFSET_END) - Data;
  614.       Printf("  DataSize\t%6ld ($%06lx) Bytes\n", Data+8, Data+8);
  615.       if(ovt)
  616.       {
  617.         for(Data = TabSize-1; Data; --Data)
  618.           ovt[Data] = ovt[Data-1];
  619.         ovt[0] = Data2;
  620.       }
  621.     }
  622.     if(ovt)
  623.     {
  624.       Data2 = 0;
  625.       while(Data2 < TabSize)
  626.       {
  627.         Printf("  Data $%04lx\t", Data2*4);
  628.         for(Data = 0; Data < 4; ++Data)
  629.         {
  630.           if(Data2 < TabSize)
  631.           {
  632.             Printf("%08lx%s", ovt[Data2], Data2 < TabSize-1 ? " " : "");
  633.             ++Data2;
  634.           }
  635.         }
  636.         Printf("\n");
  637.       }
  638.       FreeVec(ovt);
  639.     }
  640.     Printf("\n");
  641.       }
  642.       break;
  643.     case HUNK_BREAK:
  644.       Printf("HUNK_BREAK\n\n");
  645.       break;
  646.     default:
  647.       Printf("HUNK_??? ($%08lx) - Aborting!\n\n", Type);
  648.       return 1;
  649.     }
  650.   }
  651.  
  652.   return 0;
  653. }
  654.